const fs = require('fs').promises;
const fsSync = require('fs');
const path = require('path');
const crypto = require('crypto');
const config=require('./Common');
//包含的文件类型
const includeFileTypes = ['.bytes', '.proto', '.cs','.json'];
/**
 * 主函数，启动上传过程
 */

/**
 * 计算文件的MD5哈希值
 * @param {string} filePath - 文件路径
 * @returns {Promise<string>} MD5哈希字符串
 */
async function calculateMD5(filePath) {
    if (!fsSync.existsSync(filePath)) {
        throw new Error(`文件不存在: ${filePath}`);
    }

    return new Promise((resolve, reject) => {
        const hash = crypto.createHash('md5');
        const stream = fsSync.createReadStream(filePath);

        stream.on('data', chunk => hash.update(chunk));
        stream.on('end', () => resolve(hash.digest('hex')));
        stream.on('error', err => reject(new Error(`计算MD5失败: ${err.message}`)));
    });
}

/**
 * 递归获取目录下所有文件的信息（包含子目录）
 * @param {string} dir - 目录路径
 * @param {string} rootDir - 根目录路径（用于计算相对路径）
 * @returns {Promise<Array<object>>} 文件信息数组
 */
async function getAllFilesInfo(dir, rootDir) {
    const filesInfo = [];
    const entries = await fs.readdir(dir, { withFileTypes: true });

    for (const entry of entries) {
        const fullPath = path.join(dir, entry.name);
        const relativePath = path.relative(rootDir, fullPath);

        if (entry.isDirectory()) {
            // 递归处理子目录
            const subDirFiles = await getAllFilesInfo(fullPath, rootDir);
            filesInfo.push(...subDirFiles);
        } else if (entry.isFile()) {
            // 收集文件信息
            filesInfo.push({
                fullPath,
                relativePath,
                fileName: entry.name,
                directory: path.dirname(relativePath)
            });
        }
    }

    return filesInfo;
}

/**
 * 上传单个文件到服务器
 * @param {object} fileInfo - 文件信息对象
 * @returns {Promise<object>} 上传结果
 */
async function uploadSingleFile(fileInfo) {
    try {
        // 读取文件内容
        const fileContent = await fs.readFile(fileInfo.fullPath);
        
        // 计算MD5
        const fileMD5 = await calculateMD5(fileInfo.fullPath);
        let relativePath = "";
        relativePath = fileInfo.relativePath;
        relativePath = relativePath.replace(/\\/g, "/");
        console.log("relativePath:" + relativePath);
        console.log("appid:" + config.appid + "\nappkey:" + config.appkey);
        // 构建上传数据
        const uploadData = {
            fileName: fileInfo.fileName,
            relativePath: fileInfo.relativePath,
            md5: fileMD5,
            content: Array.from(fileContent)  // 转换为字节数组
        };
        const headers = {
            "appid": config.appid,
            "appkey": config.appkey, };
        const result = await config.commonPost(config.serverUrl + "UploadFileWare", uploadData, headers);
        // 处理响应
        return result;
    } catch (error) {
        return {
            success: false,
            status: 500,
            message: `上传过程出错: ${JSON.stringify(error)}`,
            file: fileInfo.relativePath
        };
    }
}

/**
 * 批量上传所有文件
 */
async function uploadAllFiles() {
    try {
        // 验证源目录是否存在
        if (!fsSync.existsSync(config.sourceDir)) {
            console.error(`${config.logTag} 错误: 源目录不存在 - ${config.sourceDir}`);
            process.exit(1);
        }

        console.log(`${config.logTag} 开始扫描目录: ${config.sourceDir}`);
        
        // 获取所有文件信息
        const allFiles = await getAllFilesInfo(config.sourceDir, config.sourceDir);
        console.log(`${config.logTag} 发现 ${allFiles.length} 个文件，准备上传...`);

        // 逐个上传文件
        let successCount = 0;
        let failCount = 0;
        let totalCount = 0;
        for (const file of allFiles) {
            if(includeFileTypes.indexOf(path.extname(file.relativePath))<0){
                continue; 
            }
            totalCount++;
            console.log(`${config.logTag} 正在上传: ${file.relativePath}`);
            
            const result = await uploadSingleFile(file);
            
            if (result.success&&result.status==200) {
                console.log("result"+JSON.stringify(result));
                successCount++;
                console.log(`${config.logTag} ✅ 成功: ${result.file}`);
            } else {
                failCount++;
                console.error(`${config.logTag} ❌ 失败 ：`+JSON.stringify(result));
                
            }
        }

        // 输出上传统计
        console.log('\n' + '='.repeat(50));
        console.log(`${config.logTag} 上传完成`);
        console.log(`${config.logTag} 总文件数: ${totalCount}`);
        console.log(`${config.logTag} 成功: ${successCount} 个`);
        console.log(`${config.logTag} 失败: ${failCount} 个`);
        console.log('='.repeat(50) + '\n');
        if(failCount!=0){
            process.exit(0);
        }

    } catch (error) {
        console.error(`${config.logTag} 致命错误: ${error.message}`);
        process.exit(1);
    }
    process.exit(0);
  
}
console.log("serverUrl:" + config.serverUrl);
// 启动上传流程
uploadAllFiles();
    
